home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / cross / avra-0.4_src.lha / avra-0.4 / expr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-24  |  13.2 KB  |  575 lines

  1. /***********************************************************************
  2.  *  avra - Assembler for the Atmel AVR microcontroller series
  3.  *  Copyright (C) 1998-1999 Jon Anders Haugum
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  18.  *  Boston, MA 02111-1307, USA.
  19.  *
  20.  *
  21.  *  Author of avra can be reached at:
  22.  *     email: jonah@omegav.ntnu.no
  23.  *     www: http://www.omegav.ntnu.no/~jonah/el/avra.html
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30.  
  31. #include "misc.h"
  32. #include "avra.h"
  33.  
  34. #define IS_UNARY(x) ((x == '!') || (x == '-') || (x == '~'))
  35. #define IS_OPERATOR(x) ((x == '+') || (x == '-') || (x == '*') || (x == '/') || (x == '%') || (x == '<') || (x == '>') || (x == '=') || (x == '!') || (x == '&') || (x == '^') || (x == '|'))
  36. #define IS_2ND_OPERATOR(x) ((x == '<') || (x == '>') || (x == '=') || (x == '&') || (x == '|'))
  37.  
  38. enum
  39.     {
  40.     OPERATOR_ERROR = 0,
  41.     OPERATOR_MUL,
  42.     OPERATOR_DIV,
  43.     OPERATOR_MOD,
  44.     OPERATOR_ADD,
  45.     OPERATOR_SUB,
  46.     OPERATOR_SHIFT_LEFT,
  47.     OPERATOR_SHIFT_RIGHT,
  48.     OPERATOR_LESS_THAN,
  49.     OPERATOR_LESS_OR_EQUAL,
  50.     OPERATOR_GREATER_THAN,
  51.     OPERATOR_GREATER_OR_EQUAL,
  52.     OPERATOR_EQUAL,
  53.     OPERATOR_NOT_EQUAL,
  54.     OPERATOR_BITWISE_AND,
  55.     OPERATOR_BITWISE_XOR,
  56.     OPERATOR_BITWISE_OR,
  57.     OPERATOR_LOGICAL_AND,
  58.     OPERATOR_LOGICAL_OR
  59.     };
  60.  
  61. enum
  62.     {
  63.     FUNCTION_LOW = 0,
  64.     FUNCTION_HIGH,
  65.     FUNCTION_BYTE2,
  66.     FUNCTION_BYTE3,
  67.     FUNCTION_BYTE4,
  68.     FUNCTION_LWRD,
  69.     FUNCTION_HWRD,
  70.     FUNCTION_PAGE,
  71.     FUNCTION_EXP2,
  72.     FUNCTION_LOG2,
  73.     FUNCTION_COUNT
  74.     };
  75.  
  76. struct element
  77.     {
  78.     struct element *next;
  79.     int data;
  80.     };
  81.  
  82. char *function_list[] =
  83.     {
  84.     "low(",
  85.     "high(",
  86.     "byte2(",
  87.     "byte3(",
  88.     "byte4(",
  89.     "lwrd(",
  90.     "hwrd(",
  91.     "page(",
  92.     "exp2(",
  93.     "log2("
  94.     };
  95.  
  96. int get_expr(struct prog_info *pi, char *data, int *value)
  97.     {
  98.     int ok = True, end = False, i, count, first_flag, length, function;
  99.     char unary, *label;
  100.     struct element *element, *first_element = NULL, *temp_element;
  101.     struct element **last_element = &first_element;
  102.  
  103.     for(i = 0, count = 0, first_flag = True, unary = 0; ; i++)
  104.         {
  105.         if(IS_HOR_SPACE(data[i]));
  106.         else if(IS_END(data[i]))
  107.             {
  108.             if((count % 2) != 1)
  109.                 print_msg(pi, MSGTYPE_ERROR, "Missing value in expression");
  110.             else
  111.                 end = True;
  112.             break;
  113.             }
  114.         else if(first_flag && IS_UNARY(data[i]))
  115.             {
  116.             unary = data[i];
  117.             first_flag = False;
  118.             }
  119.         else if((count % 2) == 1)
  120.             {
  121.             if(!IS_OPERATOR(data[i]))
  122.                 {
  123.                 print_msg(pi, MSGTYPE_ERROR, "Illegal operator '%c'", data[i]);
  124.                 break;
  125.                 }
  126.             element = malloc(sizeof(struct element));
  127.             if(!element)
  128.                 {
  129.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  130.                 ok = False;
  131.                 break;
  132.                 }
  133.             element->next = NULL;
  134.             element->data = get_operator(&data[i]);
  135.             if(element->data == OPERATOR_ERROR)
  136.                 {
  137.                 if(IS_2ND_OPERATOR(data[i + 1]))
  138.                     print_msg(pi, MSGTYPE_ERROR, "Unknown operator %c%c", data[i], data[i + 1]);
  139.                 else
  140.                     print_msg(pi, MSGTYPE_ERROR, "Unknown operator %c", data[i]);
  141.                 break;
  142.                 }
  143.             *last_element = element;
  144.             last_element = &element->next;
  145.             if(IS_2ND_OPERATOR(data[i + 1]))
  146.                 i++;
  147.             count++;
  148.             first_flag = True;
  149.             unary = 0;
  150.             }
  151.         else
  152.             {
  153.             element = malloc(sizeof(struct element));
  154.             if(!element)
  155.                 {
  156.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  157.                 ok = False;
  158.                 break;
  159.                 }
  160.             element->next = NULL;
  161.             length = 0;
  162.             if(isdigit(data[i]))
  163.                 {
  164.                 if(tolower(data[i + 1]) == 'x')
  165.                     {
  166.                     i += 2;
  167.                     while(isxdigit(data[i + length])) length++; // TODO: Sjekk overflow
  168.                     element->data = atox_n(&data[i], length);
  169.                     }
  170.                 else if(tolower(data[i + 1]) == 'b')
  171.                     {
  172.                     i += 2;
  173.                     element->data = 0;
  174.                     while((data[i + length] == '1') || (data[i + length] == '0'))
  175.                         {
  176.                         element->data <<= 1;
  177.                         element->data |= data[i + length++] - '0'; // TODO: Sjekk overflow
  178.                         }
  179.                     }
  180.                 else
  181.                     {
  182.                     while(isdigit(data[i + length])) length++;
  183.                     element->data = atoi_n(&data[i], length); // TODO: Sjekk overflow
  184.                     }
  185.                 }
  186.             else if(data[i] == '$')
  187.                 {
  188.                 i++;
  189.                 while(isxdigit(data[i + length])) length++;
  190.                 element->data = atox_n(&data[i], length); // TODO: Sjekk overflow
  191.                 }
  192.             else if(data[i] == '\'')
  193.                 {
  194.                 i++;
  195.                 element->data = data[i]; // TODO: Sjekk for siste '
  196.                 length = 2;
  197.                 }
  198.             else if(data[i] == '(')
  199.                 {
  200.                 i++;
  201.                 length = par_length(&data[i]);
  202.                 if(length == -1)
  203.                     {
  204.                     print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
  205.                     break;
  206.                     }
  207.                 data[i + length++] = '\0';
  208.                 ok = get_expr(pi, &data[i], &element->data);
  209.                 if(!ok)
  210.                     break;
  211.                 }
  212.             else if(-1 != (function = get_function(&data[i])))
  213.                 {
  214.                 while(data[i] != '(') i++;
  215.                 i++;
  216.                 length = par_length(&data[i]);
  217.                 if(length == -1)
  218.                     {
  219.                     print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
  220.                     break;
  221.                     }
  222.                 data[i + length++] = '\0';
  223.                 ok = get_expr(pi, &data[i], &element->data);
  224.                 if(!ok)
  225.                     break;
  226.                 element->data = do_function(function, element->data);
  227.                 }
  228.             else if(!nocase_strncmp(&data[i], "defined(", 8))
  229.                 {
  230.                 i += 8;
  231.                 length = par_length(&data[i]);
  232.                 if(length == -1)
  233.                     {
  234.                     print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
  235.                     break;
  236.                     }
  237.                 data[i + length++] = '\0';
  238.                 if(get_symbol(pi, &data[i], NULL))
  239.                     element->data = 1;
  240.                 else
  241.                     element->data = 0;
  242.                 }
  243.             else
  244.                 {
  245.                 while(IS_LABEL(data[i + length])) length++;
  246.                 if((length == 2) && !nocase_strncmp(&data[i], "PC", 2))
  247.                     element->data = pi->cseg_addr;
  248.                 else
  249.                     {
  250.                     label = malloc(length + 1);
  251.                     if(!label)
  252.                         {
  253.                         print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  254.                         ok = False;
  255.                         break;
  256.                         }
  257.                     strncpy(label, &data[i], length);
  258.                     label[length] = '\0';
  259.                     if(get_symbol(pi, label, &element->data))
  260.                         free(label);
  261.                     else
  262.                         {
  263.                         print_msg(pi, MSGTYPE_ERROR, "Found no label/variable/constant named %s", label);
  264.                         free(label);
  265.                         break;
  266.                         }
  267.                     }
  268.                 }
  269.             i += length - 1;
  270.             switch(unary) // TODO: Få den til å takle flere unary på rad.
  271.                 {
  272.                 case '-':
  273.                     element->data = -element->data;
  274.                     break;
  275.                 case '!':
  276.                     element->data = !element->data;
  277.                     break;
  278.                 case '~':
  279.                     element->data = ~element->data;
  280.                 }
  281.             *last_element = element;
  282.             last_element = &element->next;
  283.             count++;
  284.             first_flag = False;
  285.             }
  286.         }
  287.     if(end)
  288.         {
  289.         for(i = 13; (i >= 4) && (count != 1); i--)
  290.             {
  291.             for(element = first_element; element->next;)
  292.                 {
  293.                 if(test_operator_at_precedence(element->next->data, i)) // TODO: Vurder en hi_i for kjapphet
  294.                     {
  295.                     element->data = calc(pi, element->data, element->next->data, element->next->next->data);
  296.                     temp_element = element->next->next->next;
  297.                     free(element->next->next);
  298.                     free(element->next);
  299.                     count -= 2;
  300.                     element->next = temp_element;
  301.                     }
  302.                 else
  303.                     element = element->next->next;
  304.                 }
  305.             }
  306.         *value = first_element->data;
  307.         }
  308.     for(element = first_element; element;)
  309.         {
  310.         temp_element = element;
  311.         element = element->next;
  312.         free(temp_element);
  313.         }
  314.     return(ok);
  315.     }
  316.  
  317.  
  318. int get_operator(char *op)
  319.     {
  320.     switch(op[0])
  321.         {
  322.         case '*':
  323.             return(OPERATOR_MUL);
  324.         case '/':
  325.             return(OPERATOR_DIV);
  326.         case '%':
  327.             return(OPERATOR_MOD);
  328.         case '+':
  329.             return(OPERATOR_ADD);
  330.         case '-':
  331.             return(OPERATOR_SUB);
  332.         case '<':
  333.             switch(op[1])
  334.                 {
  335.                 case '<':
  336.                     return(OPERATOR_SHIFT_LEFT);
  337.                 case '=':
  338.                     return(OPERATOR_LESS_OR_EQUAL);
  339.                 default:
  340.                     return(OPERATOR_LESS_THAN);
  341.                 }
  342.         case '>':
  343.             switch(op[1])
  344.                 {
  345.                 case '>':
  346.                     return(OPERATOR_SHIFT_RIGHT);
  347.                 case '=':
  348.                     return(OPERATOR_GREATER_OR_EQUAL);
  349.                 default:
  350.                     return(OPERATOR_GREATER_THAN);
  351.                 }
  352.         case '=':
  353.             if(op[1] == '=')
  354.                 return(OPERATOR_EQUAL);
  355.         case '!':
  356.             if(op[1] == '=')
  357.                 return(OPERATOR_NOT_EQUAL);
  358.         case '&':
  359.             if(op[1] == '&')
  360.                 return(OPERATOR_LOGICAL_AND);
  361.             else
  362.                 return(OPERATOR_BITWISE_AND);
  363.         case '^':
  364.             return(OPERATOR_BITWISE_XOR);
  365.         case '|':
  366.             if(op[1] == '|')
  367.                 return(OPERATOR_LOGICAL_OR);
  368.             else
  369.                 return(OPERATOR_BITWISE_OR);
  370.         }
  371.     return(OPERATOR_ERROR);
  372.     }
  373.  
  374.  
  375. int test_operator_at_precedence(int operator, int precedence)
  376.     {
  377.     switch(precedence)
  378.         {
  379.         case 13:
  380.             return((operator == OPERATOR_MUL) || (operator == OPERATOR_DIV)
  381.                    || (operator == OPERATOR_MOD));
  382.         case 12:
  383.             return((operator == OPERATOR_ADD) || (operator == OPERATOR_SUB));
  384.         case 11:
  385.             return((operator == OPERATOR_SHIFT_LEFT) || (operator == OPERATOR_SHIFT_RIGHT));
  386.         case 10:
  387.             return((operator == OPERATOR_LESS_THAN) || (operator == OPERATOR_LESS_OR_EQUAL)
  388.                    || (operator == OPERATOR_GREATER_THAN) || (operator == OPERATOR_GREATER_OR_EQUAL));
  389.         case 9:
  390.             return((operator == OPERATOR_EQUAL) || (operator == OPERATOR_NOT_EQUAL));
  391.         case 8:
  392.             return(operator == OPERATOR_BITWISE_AND);
  393.         case 7:
  394.             return(operator == OPERATOR_BITWISE_XOR);
  395.         case 6:
  396.             return(operator == OPERATOR_BITWISE_OR);
  397.         case 5:
  398.             return(operator == OPERATOR_LOGICAL_AND);
  399.         default: /* Makes the compiler shut up */
  400.         case 4:
  401.             return(operator == OPERATOR_LOGICAL_OR);
  402.         }
  403.     }
  404.  
  405.  
  406. int calc(struct prog_info *pi, int left, int operator, int right) // TODO: Sjekk litt resultater
  407.     {
  408.     switch(operator)
  409.         {
  410.         case OPERATOR_MUL:
  411.             return(left * right);
  412.         case OPERATOR_DIV:
  413.             if(right == 0)
  414.                 {
  415.                 print_msg(pi, MSGTYPE_ERROR, "Division by zero");
  416.                 return(0);
  417.                 }
  418.             return(left / right);
  419.         case OPERATOR_MOD:
  420.             if(right == 0)
  421.                 {
  422.                 print_msg(pi, MSGTYPE_ERROR, "Division by zero (modulus operator)");
  423.                 return(0);
  424.                 }
  425.                 return(left % right);
  426.         case OPERATOR_ADD:
  427.             return(left + right);
  428.         case OPERATOR_SUB:
  429.             return(left - right);
  430.         case OPERATOR_SHIFT_LEFT:
  431.             return(left << right);
  432.         case OPERATOR_SHIFT_RIGHT:
  433.             return(left >> right);
  434.         case OPERATOR_LESS_THAN:
  435.             return(left < right);
  436.         case OPERATOR_LESS_OR_EQUAL:
  437.             return(left <= right);
  438.         case OPERATOR_GREATER_THAN:
  439.             return(left > right);
  440.         case OPERATOR_GREATER_OR_EQUAL:
  441.             return(left >= right);
  442.         case OPERATOR_EQUAL:
  443.             return(left == right);
  444.         case OPERATOR_NOT_EQUAL:
  445.             return(left != right);
  446.         case OPERATOR_BITWISE_AND:
  447.             return(left & right);
  448.         case OPERATOR_BITWISE_XOR:
  449.             return(left ^ right);
  450.         case OPERATOR_BITWISE_OR:
  451.             return(left | right);
  452.         case OPERATOR_LOGICAL_AND:
  453.             return(left && right);
  454.         default: /* Make the compiler shut up */
  455.         case OPERATOR_LOGICAL_OR:
  456.             return(left || right);
  457.         }
  458.     }
  459.  
  460.  
  461. int get_function(char *function)
  462.     {
  463.     int i;
  464.  
  465.     for(i = 0; i < FUNCTION_COUNT; i++)
  466.         if(!nocase_strncmp(function, function_list[i], strlen(function_list[i]))) return(i);
  467.     return(-1);
  468.     }
  469.  
  470.  
  471. int do_function(int function, int value)
  472.     {
  473.     switch(function)
  474.         {
  475.         case FUNCTION_LOW:
  476.             return(value & 0xff);
  477.         case FUNCTION_HIGH:
  478.         case FUNCTION_BYTE2:
  479.             return((value >> 8) & 0xff);
  480.         case FUNCTION_BYTE3:
  481.             return((value >> 16) & 0xff);
  482.         case FUNCTION_BYTE4:
  483.             return((value >> 24) & 0xff);
  484.         case FUNCTION_LWRD:
  485.             return(value & 0xffff);
  486.         case FUNCTION_HWRD:
  487.             return((value >> 16) & 0xffff);
  488.         case FUNCTION_PAGE:
  489.             return((value >> 16) & 0xff);
  490.         case FUNCTION_EXP2:
  491.             return(1 << value);
  492.         case FUNCTION_LOG2:
  493.             return(log2(value));
  494.         default:
  495.             return(0);
  496.         }
  497.     }
  498.  
  499.  
  500. int log2(int value)
  501.     {
  502.     int i = 0;
  503.  
  504.     while(value >>= 1) i++;
  505.     return(i);
  506.     }
  507.  
  508.  
  509. int get_symbol(struct prog_info *pi, char *label_name, int *data)
  510.     {
  511.     struct label *label;
  512.     struct macro_call *macro_call;
  513.  
  514.     for(label = pi->first_constant; label; label = label->next)
  515.         if(!nocase_strcmp(label->name, label_name))
  516.             {
  517.             if(data)
  518.                 *data = label->value;
  519.             return(True);
  520.             }
  521.  
  522.     for(label = pi->first_variable; label; label = label->next)
  523.         if(!nocase_strcmp(label->name, label_name))
  524.             {
  525.             if(data)
  526.                 *data = label->value;
  527.             return(True);
  528.             }
  529.  
  530.     for(macro_call = pi->macro_call; macro_call; macro_call = macro_call->prev_on_stack)
  531.         {
  532.         for(label = pi->macro_call->first_label; label; label = label->next)
  533.             if(!nocase_strcmp(label->name, label_name))
  534.                 {
  535.                 if(data)
  536.                     *data = label->value;
  537.                 return(True);
  538.                 }
  539.         }
  540.  
  541.     for(label = pi->first_label; label; label = label->next)
  542.         if(!nocase_strcmp(label->name, label_name))
  543.             {
  544.             if(data)
  545.                 *data = label->value;
  546.             return(True);
  547.             }
  548.  
  549.     return(False);
  550.     }
  551.  
  552.  
  553. int par_length(char *data)
  554.     {
  555.     int i = 0, b_count = 1;
  556.  
  557.     for(;;)
  558.         {
  559.         if(data[i] == ')')
  560.             {
  561.             b_count--;
  562.             if(!b_count)
  563.                 return(i);
  564.             }
  565.         else if(data[i] == '(')
  566.             b_count++;
  567.         else if(data[i] == '\0')
  568.             return(-1);
  569.         i++;
  570.         }
  571.     }
  572.  
  573.  
  574.  
  575.